//-------------------------------------------------------
// Copyright (c) 
// All rights reserved.
//
// File Name: CRegMgr.h
// File Des: 类工厂注册管理类
// File Summary:
// Cur Version: 2.0
// Author:
// Create Data:2021-5-22
// History:
//         <Author>    <Time>        <Version>      <Des>
//      zeron        2021-5-22     1.0
//      zeron        2021-6-24     2.0       支持多种类型的注册
//      lzlong       2024-1-25     3.0       加入的全局注册类单例
//-------------------------------------------------------
#pragma once
#include "CMapT.h"
#include "CRegHelperT.h"
#include "CVecT.h"
#include <string>

// 简易宏定义
#define  g_pRegMgr                              IRegMgr::getSingletonPtr()

class CRegMgr;
/// <summary>
///      分类管理所有的注册类,内部注册了插件管理器,同时可获取各类对外的接口
/// </summary>
class IRegMgr : public CSingletonT<IRegMgr>
{
public:
    IRegMgr();
    ~IRegMgr();
    virtual DMCode GetRegObj(void** ppObj,int RegType) = 0;        ///< 由各主EXE实现,获得各类对外的接口
    template<class T> DMSmartPtrT<T> GetRegObjT(int RegType)    {DMSmartPtrT<T> spObj;GetRegObj((void**)&spObj,RegType);return spObj;}

public:
    DMCode Register(IDMReg &RegObj, bool bReplace=false, bool bSetDefName=true);
    DMCode CreateRegObj(void** ppObj, LPCWSTR lpszClassName,int RegType);
    DMCode UnRegister(LPCWSTR lpszClassName,int RegType);
    DMCode SetDefRegObj(LPCWSTR lpszClassName,int RegType);
    DMCode GetDefRegObj(std::wstring &strName,int RegType);

public:
    static IRegMgr& getSingleton();     /// @copydoc DMSingletonT::getSingleton()
    static IRegMgr* getSingletonPtr();/// @copydoc DMSingletonT::getSingleton()

private:
    CRegMgr*                                m_pImpl;
};

class CRegTypeItem : public CVecT<IRegisterPtr> {
public:
  CRegTypeItem();
  virtual ~CRegTypeItem();

public:
  void PreVecObjRemove(const IRegisterPtr &obj) override;
  bool EqualVecObj(const IRegisterPtr &objsrc,
                   const IRegisterPtr &objdest) const override;
  std::wstring &GetDefRegName();

private:
  std::wstring m_strDefRegName; ///< 定义默认注册类型类名
};

typedef CRegTypeItem *CRegTypeItemPtr;
class CRegMgr : public CMapT<int, CRegTypeItemPtr> {
public:
  CRegMgr();
  ~CRegMgr();

public:
  void PreMapKeyRemove(const CRegTypeItemPtr &obj) override;
  int Register(IRegister &RegObj, bool bReplace = false,
               bool bSetDefName = true);
  template <class T>
  int Register(typename CRegHelperT<T> RegObj, bool bReplace = false,
      bool bSetDefName = true)
  {
      return Register((IRegister&)RegObj, bReplace, bSetDefName);
  }
  int CreateRegObj(void **ppObj, LPCWSTR lpszRegName, int RegType);
  int UnRegister(LPCWSTR lpszRegName, int RegType);
  int SetDefRegObj(LPCWSTR lpszRegName, int RegType);
  int GetDefRegObj(std::wstring &lpszRegName, int RegType);
};
